﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;
using System.IO;
using System.Diagnostics;
using System.Windows;
using System.Runtime.InteropServices;
using Shell32;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Threading;


/*
 * Turn off kinect interface system (DONE)
 * Open keyboard (DONE)
 * Open applications on bar
 * Open settings window (DONE)
 * Open Word, Powerpoint
 * Open Chrome  (DONE)
 * Gesture on/off
 * Mouse Control on/off
 * Show Skeletal Window
 * Show Desktop (DONE)
 * Maximize Window
 * Minimize Window
 * Close Window (DONE)
 * 
 * Folder Control
 * * Select
 * * Copy To
 * * Move To
 * * Folder Back
 * * Folder Forward
 * 
 * 
 * PowerPoint
 * * Next slide
 * * Previous slide
 * * Start slide show
 
*/

namespace Kinect_Interface_Prototype_1.Voice_Commands
{

    public class VoiceApp
    {
        private StartupProgram MainProgram;
        public bool VoiceCommandsActive { get; set; }
        public bool AllVoiceCommandsOff { get; set; }
        private bool initialized;
        public bool Initialized { get { return initialized; } }
        private ConfirmationWindow confirmation;
        public string commandKeyword;

        private Dictionary<VoiceCommandAction, VoiceCommand> voiceCommands;

        public double Confidence = 0.9;

        private static Shell32.Shell shellInterface = new Shell32.Shell();

        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static public extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);


        public IntPtr currentProcessHandle;

        int counter = 0;
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        IniFile ini = new IniFile(Constants.SettingsINI);


        private SpeechRecognitionEngine _recognizer;
        SpeechSynthesizer reader = new SpeechSynthesizer();

        public VoiceApp(StartupProgram program, ConfirmationWindow confirmationWindow, bool areActive)
        {
            MainProgram = program;

            commandKeyword = ini.IniReadValue("Voice Control", "keyword");

            voiceCommands = new Dictionary<VoiceCommandAction, VoiceCommand>
            {
                {VoiceCommandAction.Activate,  new VoiceCommand("activate voice commands", ini, commandKeyword)},
                {VoiceCommandAction.Deactivate,  new VoiceCommand("deactivate voice commands", ini, commandKeyword)},
                {VoiceCommandAction.Yes,  new VoiceCommand("yes", ini)},
                {VoiceCommandAction.No,  new VoiceCommand("no", ini)},
                {VoiceCommandAction.Maximize,  new VoiceCommand("Maximize", ini, commandKeyword)},
                {VoiceCommandAction.Minimize,  new VoiceCommand("Minimize", ini, commandKeyword)},
                {VoiceCommandAction.ApplicationOne,  new VoiceCommand("Application one", ini, commandKeyword)},
                {VoiceCommandAction.ApplicationTwo,  new VoiceCommand("Application two", ini, commandKeyword)},
                {VoiceCommandAction.ApplicationThree,  new VoiceCommand("Application three", ini, commandKeyword)},
                {VoiceCommandAction.ApplicationFour,  new VoiceCommand("Application four", ini, commandKeyword)},
                {VoiceCommandAction.ApplicationFive,  new VoiceCommand("Application five", ini, commandKeyword)},

                {VoiceCommandAction.Shutdown,  new VoiceCommand("shutdown", ini, commandKeyword)},
                {VoiceCommandAction.Logoff,  new VoiceCommand("logoff", ini, commandKeyword)},
                {VoiceCommandAction.Restart,  new VoiceCommand("restart", ini, commandKeyword)},
                {VoiceCommandAction.Hibernate,  new VoiceCommand("Hibernate", ini, commandKeyword)},
                {VoiceCommandAction.LockComputer,  new VoiceCommand("lock computer", ini, commandKeyword)},
                {VoiceCommandAction.CloseWindow,  new VoiceCommand("close window", ini, commandKeyword)},
                {VoiceCommandAction.ShowDesktop,  new VoiceCommand("show desktop", ini, commandKeyword)},
                {VoiceCommandAction.WindowSwitcher,  new VoiceCommand("window switcher", ini, commandKeyword)},
                {VoiceCommandAction.Search,  new VoiceCommand("search", ini, commandKeyword)},
                
                {VoiceCommandAction.SystemShutdown,  new VoiceCommand("system shutdown", ini, commandKeyword)},
                {VoiceCommandAction.OpenSettings,  new VoiceCommand("open settings", ini, commandKeyword)},
                {VoiceCommandAction.CloseSettings,  new VoiceCommand("close settings", ini, commandKeyword)},
                {VoiceCommandAction.OpenKeyboard,  new VoiceCommand("open keyboard", ini, commandKeyword)},
                {VoiceCommandAction.CloseKeyboard,  new VoiceCommand("close keyboard", ini, commandKeyword)},
                {VoiceCommandAction.MouseControlOn,  new VoiceCommand("mouse control on", ini, commandKeyword)},
                {VoiceCommandAction.MouseControlOff,  new VoiceCommand("mouse control off", ini, commandKeyword)},

                {VoiceCommandAction.Firefox,  new VoiceCommand("firefox", ini, commandKeyword)},
                {VoiceCommandAction.InternetExplorer,  new VoiceCommand("internet explorer", ini, commandKeyword)},
                {VoiceCommandAction.Chrome,  new VoiceCommand("chrome",ini, commandKeyword)},
            };
            
            try
            {               
                VoiceCommandsActive = areActive;

                confirmation = confirmationWindow;

                timer.Tick += new EventHandler(timer_Tick);

                _recognizer = new SpeechRecognitionEngine();
                _recognizer.SetInputToDefaultAudioDevice();

                Choices choices = new Choices(voiceCommands.Values.Select(x => x.CommandWords).ToArray());

                GrammarBuilder grBuilder = new GrammarBuilder(choices);
                Grammar grammar = new Grammar(grBuilder);
                _recognizer.LoadGrammar(grammar);

                _recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(_recognizer_SpeechRecognized);
                _recognizer.RecognizeAsync(RecognizeMode.Multiple);

                initialized = true;
                MainProgram.ControlForm_ActivateVoiceCommandsSwitch(true);
            }
            catch (Exception)
            {
                initialized = false;
                MainProgram.ControlForm_ActivateVoiceCommandsSwitch(false);
                System.Windows.MessageBox.Show("Voice Commands unable to be initialized.");       
            }
        }


        private void _recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            //if (e.Result.Confidence > Confidence) { reader.SpeakAsync(e.Result.Text); }

            // Check box in settings form is unchecked, all voice commands are off.
            if (AllVoiceCommandsOff)
                return;

            if (VoiceCommandsActive)
            {
                #region App Dock Application One
                
                if (voiceCommands[VoiceCommandAction.ApplicationOne].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ApplicationOne].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ApplicationOne].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.AppDock_AppClick(1);
                        }
                    }
                }
                #endregion

                #region App Dock Application Two
                if (voiceCommands[VoiceCommandAction.ApplicationTwo].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ApplicationTwo].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ApplicationTwo].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.AppDock_AppClick(2);
                        }
                    }
                }
                #endregion

                #region App Dock Application Three
                if (voiceCommands[VoiceCommandAction.ApplicationThree].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ApplicationThree].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ApplicationThree].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.AppDock_AppClick(3);
                        }
                    }
                }
                #endregion

                #region App Dock Application Four
                if (voiceCommands[VoiceCommandAction.ApplicationFour].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ApplicationFour].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ApplicationFour].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.AppDock_AppClick(4);
                        }
                    }
                }
                #endregion

                #region App Dock Application Five
                if (voiceCommands[VoiceCommandAction.ApplicationFive].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ApplicationFive].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ApplicationFive].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.AppDock_AppClick(5);
                        }
                    }
                }
                #endregion

                #region Mouse Control On

                if (voiceCommands[VoiceCommandAction.MouseControlOn].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.MouseControlOn].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.MouseControlOn].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.ControlForm_SwitchOn(Interface_Design.OnOffControlType.MouseControl);
                            MainProgram.KinectForm_ToggleMouseControl(true);
                        }
                    }
                }
                #endregion

                #region Mouse Control Off

                if (voiceCommands[VoiceCommandAction.MouseControlOff].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.MouseControlOff].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.MouseControlOff].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.ControlForm_SwitchOff(Interface_Design.OnOffControlType.MouseControl);
                            MainProgram.KinectForm_ToggleMouseControl(false);
                        }
                    }
                }
                #endregion

                #region Minimize 
                if (voiceCommands[VoiceCommandAction.Minimize].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Minimize].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Minimize].Confidence && confirmation.Visible == false)
                        {
                            IntPtr mainWindow = GetForegroundWindow();

                            // Prevents minimizing App Dock, Control Form, and keyboard
                            if (!mainWindow.Equals(IntPtr.Zero) && !mainWindow.Equals(MainProgram.AppDock_Handle())
                                && !mainWindow.Equals(MainProgram.ControlForm_Handle()) && !mainWindow.Equals(MainProgram.VirtualKeyboard_Handle()))
                            {
                                ShowWindow(mainWindow, 2);
                            }
                        }
                    }
                }
                #endregion

                #region Maximize
                if (voiceCommands[VoiceCommandAction.Maximize].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Maximize].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Maximize].Confidence && confirmation.Visible == false)
                        {
                            IntPtr mainWindow = GetForegroundWindow();

                            // Prevents maximizing App Dock, Control Form, and keyboard
                            if (!mainWindow.Equals(IntPtr.Zero) && !mainWindow.Equals(MainProgram.AppDock_Handle())
                                && !mainWindow.Equals(MainProgram.ControlForm_Handle()) && !mainWindow.Equals(MainProgram.VirtualKeyboard_Handle()))
                            {
                                ShowWindow(mainWindow, 3);
                            }
                        }
                    }
                }
                #endregion

                #region Open Keyboard
                if (voiceCommands[VoiceCommandAction.OpenKeyboard].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.OpenKeyboard].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.OpenKeyboard].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.VirtualKeyboard_Show();
                        }
                    }
                }
                #endregion

                #region Close Keyboard
                if (voiceCommands[VoiceCommandAction.CloseKeyboard].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.CloseKeyboard].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.CloseKeyboard].Confidence && confirmation.Visible == false)
                        {
                            MainProgram.VirtualKeyboard_Hide();
                        }
                    }
                }
                #endregion

                #region Close Window
                if (voiceCommands[VoiceCommandAction.CloseWindow].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.CloseWindow].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.CloseWindow].Confidence && confirmation.Visible == false)
                        {

                            // change this to showWindow with the correct flag
                            IntPtr iHandle = GetForegroundWindow();
                            SetForegroundWindow(iHandle);
                            System.Windows.Forms.SendKeys.Send("%({F4})"); // Send alt+F4  
                        }
                    }
                }
                #endregion

                #region Search
                if (voiceCommands[VoiceCommandAction.Search].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Search].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Search].Confidence && confirmation.Visible == false)
                        {
                            counter = 0;
                            System.Windows.Clipboard.Clear();

                            // get active window
                            SetForegroundWindow(GetForegroundWindow());
                            SendKeys.Send("^(c)");
                            timer.Interval = 100;
                            timer.Enabled = true;
                            timer.Start();
                        }
                    }
                }
                #endregion

                #region Window Switcher
                if (voiceCommands[VoiceCommandAction.WindowSwitcher].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.WindowSwitcher].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.WindowSwitcher].Confidence && confirmation.Visible == false)
                        {
                            //IntPtr lHwnd = FindWindow("Shell_TrayWnd", null);
                            //SendMessage(lHwnd, WM_COMMAND, (IntPtr)MIN_THIS, IntPtr.Zero);

                            shellInterface.WindowSwitcher();
                        }

                    }
                }
                #endregion

                #region Lock Computer
                if (voiceCommands[VoiceCommandAction.LockComputer].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.LockComputer].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.LockComputer].Confidence && confirmation.Visible == false)
                        {
                            System.Diagnostics.Process.Start("rundll32.exe", "user32.dll,LockWorkStation");
                        }
                    }
                }
                #endregion

                #region Show Desktop
                if (voiceCommands[VoiceCommandAction.ShowDesktop].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.ShowDesktop].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.ShowDesktop].Confidence && confirmation.Visible == false)
                        {
                            shellInterface.ToggleDesktop();
                        }
                    }
                }
                #endregion

                #region Open Settings
                if (voiceCommands[VoiceCommandAction.OpenSettings].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.OpenSettings].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.OpenSettings].Confidence && confirmation.Visible == false)
                        {
                            // show settings form
                            MainProgram.SettingsForm_ToggleVisibility(true);

                        }
                    }
                }
                #endregion

                #region Close Settings
                if (voiceCommands[VoiceCommandAction.CloseSettings].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.CloseSettings].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.CloseSettings].Confidence && confirmation.Visible == false)
                        {
                            // hide settings form
                            MainProgram.SettingsForm_ToggleVisibility(false);
                        }
                    }
                }
                #endregion

                #region System Shutdown
                if (voiceCommands[VoiceCommandAction.SystemShutdown].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.SystemShutdown].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.SystemShutdown].Confidence && confirmation.Visible == false)
                        {
                            confirmation.command = voiceCommands[VoiceCommandAction.SystemShutdown].OriginalWords;
                            confirmation.textLabel.Text = "Are you sure you want to exit the system?";
                            confirmation.Show();
                        }
                    }
                }
                #endregion

                #region Chrome
                if (voiceCommands[VoiceCommandAction.Chrome].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Chrome].CommandWords)
                    {

                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Chrome].Confidence && confirmation.Visible == false)
                        {
                            try
                            {
                                System.Diagnostics.Process.Start("CHROME.EXE");
                            }
                            catch (Exception)
                            {
                                System.Windows.MessageBox.Show("CHROME.EXE does not exist");
                            }
                        }
                    }
                }
                #endregion

                #region Internet Explorer
                if (voiceCommands[VoiceCommandAction.InternetExplorer].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.InternetExplorer].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.InternetExplorer].Confidence && confirmation.Visible == false)
                        {
                            try
                            {
                                System.Diagnostics.Process.Start("IEXPLORE.EXE");
                            }
                            catch (Exception)
                            {

                                System.Windows.MessageBox.Show("IEXPLORE.EXE does not exist");
                            }
                        }
                    }
                }
                #endregion

                #region Firefox
                if (voiceCommands[VoiceCommandAction.Firefox].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Firefox].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Firefox].Confidence && confirmation.Visible == false)
                        {
                            try
                            {
                                if (!isProcessRunning("firefox"))
                                {
                                    System.Diagnostics.Process.Start("FIREFOX.EXE");
                                }
                                else
                                {
                                    //SetForegroundWindow(currentProcessHandle);
                                    ShowWindow(currentProcessHandle, 3);
                                }
                            }
                            catch (Exception)
                            {

                                System.Windows.MessageBox.Show("FIREFOX.EXE does not exist");
                            }
                        }
                    }
                }
                #endregion

                #region Yes
                if (voiceCommands[VoiceCommandAction.Yes].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Yes].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.Yes].Confidence && confirmation.Visible == true)
                        {
                            confirmation.YesButton_Click(sender, e);
                        }
                    }
                }
                #endregion

                #region No
                if (voiceCommands[VoiceCommandAction.No].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.No].CommandWords)
                    {
                        if (e.Result.Confidence > voiceCommands[VoiceCommandAction.No].Confidence && confirmation.Visible == true)
                        {
                            confirmation.NoButton_Click(sender, e);
                        }
                    }
                }
                #endregion

                #region Logoff
                if (voiceCommands[VoiceCommandAction.Logoff].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Logoff].CommandWords)
                    {
                        confirmation.command = voiceCommands[VoiceCommandAction.Logoff].OriginalWords;
                        confirmation.textLabel.Text = "Are you sure you want to " + voiceCommands[VoiceCommandAction.Logoff].OriginalWords + "?";
                        logoff(e.Result.Confidence);

                    }
                }
                #endregion

                #region Shutdown
                if (voiceCommands[VoiceCommandAction.Shutdown].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Shutdown].CommandWords)
                    {
                        confirmation.command = voiceCommands[VoiceCommandAction.Shutdown].OriginalWords;
                        confirmation.textLabel.Text = "Are you sure you want to " + voiceCommands[VoiceCommandAction.Shutdown].OriginalWords + "?";
                        shutDown(e.Result.Confidence);
                    }
                }
                #endregion

                #region Restart
                if (voiceCommands[VoiceCommandAction.Restart].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Restart].CommandWords)
                    {
                        confirmation.command = voiceCommands[VoiceCommandAction.Restart].OriginalWords;
                        confirmation.textLabel.Text = "Are you sure you want to " + voiceCommands[VoiceCommandAction.Restart].OriginalWords + "?";
                        restart(e.Result.Confidence);
                    }
                }
                #endregion

                #region Hibernate
                if (voiceCommands[VoiceCommandAction.Hibernate].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Hibernate].CommandWords)
                    {
                        confirmation.command = voiceCommands[VoiceCommandAction.Hibernate].OriginalWords;
                        confirmation.textLabel.Text = "Are you sure you want to " + voiceCommands[VoiceCommandAction.Hibernate].OriginalWords + "?";
                        Hibernate(e.Result.Confidence);
                    }
                }
                #endregion

                #region Deactivate
                if (voiceCommands[VoiceCommandAction.Deactivate].Active)
                {
                    if (e.Result.Text == voiceCommands[VoiceCommandAction.Deactivate].CommandWords)
                    {
                        if (e.Result.Confidence > Confidence && confirmation.Visible == false)
                        {
                            //textBox1.Text = "deactivated";
                            VoiceCommandsActive = false;
                            MainProgram.ControlForm_ToggleVoiceCommandsSwitch(false);
                        }
                    }
                }
                #endregion

                /*
                // if () folder form is visible
                {
                    if (e.Result.Confidence > Confidence && confirmation.Visible == false)
                    {
                        if (e.Result.Text == "select")
                        {
                            MessageBox.Show(e.Result.Text);
                        }
                    }
                }
                    * */
            }

            #region Activate
            if (voiceCommands[VoiceCommandAction.Activate].Active)
            {
                if (e.Result.Text == voiceCommands[VoiceCommandAction.Activate].CommandWords)
                {
                    if (e.Result.Confidence > Confidence && confirmation.Visible == false)
                    {
                        //textBox1.Text = "activated";
                        VoiceCommandsActive = true;
                        MainProgram.ControlForm_ToggleVoiceCommandsSwitch(true);
                    }
                }
            }
            #endregion
        }

        void logoff(float newConf)
        {
            if (newConf >= voiceCommands[VoiceCommandAction.Logoff].Confidence && confirmation.Visible == false)
            {
                confirmation.Show();
            }
        }

        void shutDown(float newConf)
        {
            if (newConf >= voiceCommands[VoiceCommandAction.Shutdown].Confidence && confirmation.Visible == false)
            {
                confirmation.Show();
            }
        }

        void restart(float newConf)
        {
            if (newConf >= voiceCommands[VoiceCommandAction.Restart].Confidence && confirmation.Visible == false)
            {
                confirmation.Show();
            }
        }

        void Hibernate(float newConf)
        {
            if (newConf >= voiceCommands[VoiceCommandAction.Hibernate].Confidence && confirmation.Visible == false)
            {
                confirmation.Show();
            }
        }

        static void SearchGoogle(string t)
        {
            Process.Start("http://google.com/search?q=" + t);
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (counter == 5)
            {
                timer.Stop();
                if (System.Windows.Forms.Clipboard.ContainsText())
                {
                    //System.Windows.MessageBox.Show(Convert.ToString(System.Windows.Clipboard.GetText()));
                    SearchGoogle(Convert.ToString(System.Windows.Clipboard.GetText()));                   
                }
                else
                {
                    reader.SpeakAsync("Please select some text.");
                    System.Windows.MessageBox.Show("Please select some text.");                  
                }        
            }
            else
            {
                counter++;
            }
        }

        public bool isProcessRunning(string process)
        {
            Process[] processlist = Process.GetProcesses();
            bool processIsRunningFlag = false;

            foreach (Process theprocess in processlist)
            {
                if (theprocess.ProcessName.ToString() == process)
                {
                    processIsRunningFlag = true;
                    currentProcessHandle = theprocess.MainWindowHandle;
                }
            }

            return processIsRunningFlag;
        }

        // Set the confidence of a voice command
        public void SetVoiceCommandConfidence(VoiceCommandAction commandAction, double confidence)
        {
            voiceCommands[commandAction].Confidence = confidence / 100; // confidence is passed as a percent (change to decimal)
        }

        // Set whether a voice command is active or not
        public void SetVoiceCommandActive(VoiceCommandAction commandAction, bool active)
        {
            voiceCommands[commandAction].Active = active;
        }

        // does not include the command keyword
        public string GetVoiceCommandString(VoiceCommandAction commandAction)
        {
            return voiceCommands[commandAction].OriginalWords;
        }

        
        public void Reset()
        {
            Dispose();
            commandKeyword = ini.IniReadValue("Voice Control", "keyword");

            UpdateToNewKeyword();

            try
            {
                VoiceCommandsActive = MainProgram.ControlForm_GetSwitchOn(Interface_Design.OnOffControlType.VoiceCommands);

                _recognizer = new SpeechRecognitionEngine();
                _recognizer.SetInputToDefaultAudioDevice();

                Choices choices = new Choices(voiceCommands.Values.Select(x => x.CommandWords).ToArray());

                GrammarBuilder grBuilder = new GrammarBuilder(choices);
                Grammar grammar = new Grammar(grBuilder);
                _recognizer.LoadGrammar(grammar);

                _recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(_recognizer_SpeechRecognized);
                _recognizer.RecognizeAsync(RecognizeMode.Multiple);

                initialized = true;
                MainProgram.ControlForm_ActivateVoiceCommandsSwitch(true);
            }
            catch (Exception)
            {
                initialized = false;
                MainProgram.ControlForm_ActivateVoiceCommandsSwitch(false);
                System.Windows.MessageBox.Show("Voice Commands unable to be initialized.");
            }
        }

        private void UpdateToNewKeyword()
        {
            foreach (VoiceCommand voiceCommand in voiceCommands.Values)
            {
                voiceCommand.CommandWords = commandKeyword + " " + voiceCommand.OriginalWords;
            }
        }

        private void Dispose()
        {
            _recognizer.SpeechRecognized -= new EventHandler<SpeechRecognizedEventArgs>(_recognizer_SpeechRecognized);
            Thread oThread = new Thread(new ThreadStart(_recognizer.Dispose));
            oThread.Start(); 
        }
    }

    public class VoiceCommand
    {
        public string CommandWords { get; set; }
        public string OriginalWords { get; set; } // does not include the command keyword
        public double Confidence { get; set; }
        public bool Active { get; set; }

        public VoiceCommand(string commandWords, IniFile ini)
        {
            CommandWords = commandWords;
            OriginalWords = commandWords;
            Confidence = Double.Parse(ini.IniReadValue("Voice Control", commandWords.Replace(" ", String.Empty) + "Confidence")) / 100; // confidence is passed as a percent (change to decimal)
            Active = Boolean.Parse(ini.IniReadValue("Voice Control", commandWords.Replace(" ", String.Empty)));
        }

        public VoiceCommand(string commandWords, IniFile ini, string commandKeyword)
        {
            CommandWords = commandKeyword + " " + commandWords;
            OriginalWords = commandWords;
            Confidence = Double.Parse(ini.IniReadValue("Voice Control", commandWords.Replace(" ", String.Empty) + "Confidence")) / 100; // confidence is passed as a percent (change to decimal)
            Active = Boolean.Parse(ini.IniReadValue("Voice Control", commandWords.Replace(" ", String.Empty)));
        }
    }

    public enum VoiceCommandAction
    {
        Activate,
        Deactivate,
        Yes,
        No,
        Select,
        Shutdown,
        Logoff,
        Restart,
        Hibernate,
        Firefox,
        InternetExplorer,
        Chrome,
        SystemShutdown,
        OpenSettings,
        CloseSettings,
        ShowDesktop,
        LockComputer,
        WindowSwitcher,
        Search,
        CloseWindow,
        OpenKeyboard,
        CloseKeyboard,
        Maximize,
        Minimize,
        ApplicationOne,
        ApplicationTwo,
        ApplicationThree,
        ApplicationFour,
        ApplicationFive,
        MouseControlOn,
        MouseControlOff
    }
}
